package com.svpino.netflix.model;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.svpino.netflix.LateBindingList;
import com.svpino.netflix.Proxy;
import com.svpino.netflix.parsers.FieldParser;

public class CatalogItem extends Item {

	private final Proxy proxy;
	private final String id;
	private final String title;
	private int releaseYear;
	private float rating;
	private Integer maturityLevel;
	private String synopsis;
	private Element synopsisElement;
	private Element catalogTitleElement;
	private LateBindingList<Format> formats;

	public CatalogItem(Proxy proxy, String id, String title) {
		this.proxy = proxy;
		this.id = id;
		this.title = title;
	}

	public CatalogItem(
			Proxy proxy,
			String id,
			String title,
			int releaseYear,
			float rating,
			Integer maturityLevel,
			Element catalogTitleElement) throws Exception {
		this.proxy = proxy;
		this.id = id;
		this.title = title;
		this.releaseYear = releaseYear;
		this.rating = rating;
		this.maturityLevel = maturityLevel;
		this.synopsis = null;
		this.catalogTitleElement = catalogTitleElement;

		initialize();
	}

	private void initialize() throws Exception {
		XPathFactory factory = XPathFactory.newInstance();
		XPath xPath = factory.newXPath();
		this.synopsisElement = (Element) ((NodeList) xPath.compile("./link[@rel='http://schemas.netflix.com/catalog/titles/synopsis']").evaluate(this.catalogTitleElement, XPathConstants.NODESET)).item(0);
	}

	public String getTitle() {
		return this.title;
	}

	public Integer getReleaseYear() {
		return this.releaseYear;
	}

	public float getRating() {
		return this.rating;
	}

	public Integer getMaturityLevel() {
		return this.maturityLevel;
	}

	public String getSynopsis() throws Exception {
		if (this.synopsis == null) {
			FieldParser parser = this.proxy.getFieldParser();

			if (this.synopsisElement == null || this.synopsisElement.getChildNodes().getLength() == 0) {
				this.synopsis = parser.parse(this.id + "/synopsis");
			}
			else {
				this.synopsis = parser.parse(this.synopsisElement);
			}
		}

		return this.synopsis;
	}

	public LateBindingList<Format> getFormats() {
		return this.formats;
	}
}
